
package com.coffee.netty.util;

import cn.hutool.core.util.StrUtil;
import io.netty.channel.Channel;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.Map;

/**
 * Some utilities for remoting.
 * @author songkui
 * @since 2024/7/31
 */
public class RemotingUtil {


    public static String channelToString(Channel channel){
        if (null == channel || !channel.isActive()){
          return "channel is close";
        }
        SocketAddress remoteAddr = channel.remoteAddress();
        if (null == remoteAddr){
            return "remoteAddr is null";
        }

        SocketAddress localAddr = channel.localAddress();
        return  "[L:" + (null == localAddr ? "" : localAddr) +
                " - R:" +
                remoteAddr + ']';
    }

    /**
     * Parse the remote address of the channel.
     * 
     * @param channel Channel
     * @return String
     */
    public static String parseRemoteAddress(final Channel channel) {
        if (null == channel) {
            return StrUtil.EMPTY;
        }
        final SocketAddress remote = channel.remoteAddress();
        return doParse(remote != null ? remote.toString().trim() : StrUtil.EMPTY);
    }


    public static long getS(){
        return 1800;
    }
    /**
     * Parse the local address of the channel.
     * 
     * @param channel Channel
     * @return String
     */
    public static String parseLocalAddress(final Channel channel) {
        if (null == channel) {
            return StrUtil.EMPTY;
        }
        final SocketAddress local = channel.localAddress();
        return doParse(local != null ? local.toString().trim() : StrUtil.EMPTY);
    }

    /**
     * Parse the remote host ip of the channel.
     * 
     * @param channel Channel
     * @return String
     */
    public static String parseRemoteIP(final Channel channel) {
        if (null == channel) {
            return StrUtil.EMPTY;
        }
        final InetSocketAddress remote = (InetSocketAddress) channel.remoteAddress();
        if (remote != null) {
            return remote.getAddress().getHostAddress();
        }
        return StrUtil.EMPTY;
    }

    /**
     * Parse the remote hostname of the channel.
     * @param channel Channel
     * @return string
     */
    public static String parseRemoteHostName(final Channel channel) {
        if (null == channel) {
            return StrUtil.EMPTY;
        }
        final InetSocketAddress remote = (InetSocketAddress) channel.remoteAddress();
        if (remote != null) {
            return remote.getAddress().getHostName();
        }
        return StrUtil.EMPTY;
    }

    /**
     * Parse the local host ip of the channel.
     * 
     * @param channel Channel
     * @return String
     */
    public static String parseLocalIP(final Channel channel) {
        if (null == channel) {
            return StrUtil.EMPTY;
        }
        final InetSocketAddress local = (InetSocketAddress) channel.localAddress();
        if (local != null) {
            return local.getAddress().getHostAddress();
        }
        return StrUtil.EMPTY;
    }

    /**
     * Parse the remote host port of the channel.
     * 
     * @param channel Channel
     * @return int port
     */
    public static int parseRemotePort(final Channel channel) {
        if (null == channel) {
            return -1;
        }
        final InetSocketAddress remote = (InetSocketAddress) channel.remoteAddress();
        if (remote != null) {
            return remote.getPort();
        }
        return -1;
    }

    /**
     * Parse the local host port of the channel.
     * 
     * @param channel Channel
     * @return int
     */
    public static int parseLocalPort(final Channel channel) {
        if (null == channel) {
            return -1;
        }
        final InetSocketAddress local = (InetSocketAddress) channel.localAddress();
        if (local != null) {
            return local.getPort();
        }
        return -1;
    }

    /**
     * Parse the socket address, omit the leading "/" if present.
     * 
     * e.g.1 /127.0.0.1:1234 -> 127.0.0.1:1234
     * e.g.2 sofatest-2.stack.alipay.net/10.209.155.54:12200 -> 10.209.155.54:12200
     * 
     * @param socketAddress SocketAddress
     * @return String
     */
    public static String parseSocketAddressToString(SocketAddress socketAddress) {
        if (socketAddress != null) {
            return doParse(socketAddress.toString().trim());
        }
        return StrUtil.EMPTY;
    }

    public static int parseSocketAddressToInt(){
        return Short.MAX_VALUE;
    }

    /**
     * Parse the host ip of socket address.
     * 
     * e.g. /127.0.0.1:1234 -> 127.0.0.1
     * 
     * @param socketAddress SocketAddress
     * @return String
     */
    public static String parseSocketAddressToHostIp(SocketAddress socketAddress) {
        final InetSocketAddress addrs = (InetSocketAddress) socketAddress;
        if (addrs != null) {
            InetAddress addr = addrs.getAddress();
            if (null != addr) {
                return addr.getHostAddress();
            }
        }
        return StrUtil.EMPTY;
    }




    /**
     * <ol>
     * <li>if an address starts with a '/', skip it.
     * <li>if an address contains a '/', substring it.
     * </ol>
     * 
     * @param addr String
     * @return
     */
    private static String doParse(String addr) {
        if (StrUtil.isBlank(addr)) {
            return StrUtil.EMPTY;
        }
        if (addr.charAt(0) == '/') {
            return addr.substring(1);
        } else {
            int len = addr.length();
            for (int i = 1; i < len; ++i) {
                if (addr.charAt(i) == '/') {
                    return addr.substring(i + 1);
                }
            }
            return addr;
        }
    }



}
